package com.netx.generics.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.netx.generics.basic.Checker;
import com.netx.generics.basic.IntegrityException;

class FileImpl extends FileObjectImpl implements File {

	protected FileImpl(FileSystem fs, ProtocolImpl provider) {
		super(fs, provider);
		if(provider.hadTrailingSlash) {
			throw new IllegalArgumentException("'"+provider.path+"/': file path cannot have trailing '/'");
		}
	}
	
	public String getNameWithoutExtension() {
		String name = getName();
		if(name.contains(".")) {
			return name.substring(0, name.lastIndexOf("."));
		}
		else {
			return name;
		}
	}
	
	public int compareTo(Object obj) {
		Checker.checkNull(obj, "obj");
		File file = (File)obj;
		try {
			boolean result = getName().equals(file.getName()) && getSize()==file.getSize() && getLastModified().equals(file.getLastModified());
			return result ? 0 : -1;
		}
		catch(IOException io) {
			//TODO what to do here??
			throw new IntegrityException(io);
		}
	}

	public long getSize() throws IOException {
		try {
			return provider.getSize();
		}
		catch(IOException io) {
			throw provider.translate(io, getPath());
		}
		catch(RuntimeException re) {
			throw provider.translate(re, getPath());
		}
	}

	public boolean delete() throws IOException {
		try {
			return provider.delete();
		}
		catch(IOException io) {
			throw provider.translate(io, getPath());
		}
		catch(RuntimeException re) {
			throw provider.translate(re, getPath());
		}
	}
	
	public void copyTo(Directory dir, String name) throws IOException {
		Checker.checkNull(dir, "dir");
		Checker.checkEmpty(name, "name");
		// Note: createFile throws ObjectAlreadyExistsException
		File dest = dir.createFile(name);
		try {
			InputStream in = getInputStream();
			OutputStream out = dest.getOutputStream();
			Streams.copy(in, out);
			out.close();
			in.close();
		}
		catch(IOException io) {
			throw provider.translate(io, getPath());
		}
		catch(RuntimeException re) {
			throw provider.translate(re, getPath());
		}
		dest.setLastModified(getLastModified());
		if(isReadOnly()) {
			dest.makeReadOnly();
		}
	}

	public InputStream getInputStream() throws IOException {
		try {
			return provider.getInputStream();
		}
		catch(IOException io) {
			throw provider.translate(io, getPath());
		}
		catch(RuntimeException re) {
			throw provider.translate(re, getPath());
		}
	}

	public OutputStream getOutputStream() throws IOException {
		return getOutputStream(false);
	}

	public OutputStream getOutputStream(boolean append) throws IOException {
		try {
			return provider.getOutputStream(append);
		}
		catch(IOException io) {
			throw provider.translate(io, getPath());
		}
		catch(RuntimeException re) {
			throw provider.translate(re, getPath());
		}
	}
}
